package org.gdstash.character;

import org.gdstash.file.GDReader;
import org.gdstash.file.GDWriter;
import org.gdstash.util.FileVersionException;
import org.gdstash.util.GDMsgFormatter;

import java.io.IOException;

public class GDCharInfo {
    private static final int VERSION_2 = 2;
    private static final int VERSION_3 = 3;
    private static final int VERSION_4 = 4;
    private static final int VERSION_5 = 5;
    private static final int BLOCK = 1;
    private int version;
    private byte isInMainQuest;
    private byte hasBeenInGame;
    private byte difficulty;
    private byte greatestCampaignDifficulty;
    private int money;
    private byte greatestCrucibleDifficulty;
    private int tributes;
    private byte compassState;
    private int lootMode;
    private byte skillWindowHelp;
    private byte alternateConfig;
    private byte alternateConfigEnabled;
    private String texture;
    private byte[] lootFilters;
    private boolean changed;

    public boolean isInMainQuest() {
        return this.isInMainQuest == 1;
    }

    public byte getGreatestCampaignDifficulty() {
        return this.greatestCampaignDifficulty;
    }

    public byte getGreatestCrucibleDifficulty() {
        return this.greatestCrucibleDifficulty;
    }

    public int getMoney() {
        return this.money;
    }

    public int getTributes() {
        return this.tributes;
    }

    public boolean hasChanged() {
        return this.changed;
    }

    public void setInMainQuest(final boolean isInMainQuest) {
        if (isInMainQuest) {
            this.isInMainQuest = 1;
        } else {
            this.isInMainQuest = 0;
        }
    }

    public void setGreatestCampaignDifficulty(final byte greatestCampaignDifficulty) {
        this.greatestCampaignDifficulty = greatestCampaignDifficulty;
        if (greatestCampaignDifficulty < 0) {
            this.greatestCampaignDifficulty = 0;
        }
        if (greatestCampaignDifficulty > 2) {
            this.greatestCampaignDifficulty = 2;
        }
        this.changed = true;
    }

    public void setGreatestCrucibleDifficulty(final byte greatestCrucibleDifficulty) {
        this.greatestCrucibleDifficulty = greatestCrucibleDifficulty;
        if (greatestCrucibleDifficulty < 0) {
            this.greatestCrucibleDifficulty = 0;
        }
        if (greatestCrucibleDifficulty > 2) {
            this.greatestCrucibleDifficulty = 2;
        }
        this.changed = true;
    }

    public void setMoney(final int money) {
        this.money = money;
        this.changed = true;
    }

    public void setTributes(final int tributes) {
        this.tributes = tributes;
        this.changed = true;
    }

    public void setTexture(final String texture) {
        this.texture = texture;
        this.changed = true;
    }

    public void read() throws IOException {
        int val = 0;
        final GDReader.Block block = new GDReader.Block();
        val = GDReader.readBlockStart(block);
        if (val != 1) {
            throw new FileVersionException(GDMsgFormatter.getString(GDMsgFormatter.rbMsg, "ERR_UNSUPPORTED_VERSION"));
        }
        this.version = GDReader.readEncInt(true);
        if (this.version != 3 && this.version != 4 && this.version != 5) {
            throw new FileVersionException(GDMsgFormatter.getString(GDMsgFormatter.rbMsg, "ERR_UNSUPPORTED_VERSION"));
        }
        this.isInMainQuest = GDReader.readEncByte();
        this.hasBeenInGame = GDReader.readEncByte();
        this.difficulty = GDReader.readEncByte();
        this.greatestCampaignDifficulty = GDReader.readEncByte();
        this.money = GDReader.readEncInt(true);
        if (this.version >= 4) {
            this.greatestCrucibleDifficulty = GDReader.readEncByte();
            this.tributes = GDReader.readEncInt(true);
        }
        this.compassState = GDReader.readEncByte();
        if (this.version >= 2 && this.version <= 4) {
            this.lootMode = GDReader.readEncInt(true);
        }
        this.skillWindowHelp = GDReader.readEncByte();
        this.alternateConfig = GDReader.readEncByte();
        this.alternateConfigEnabled = GDReader.readEncByte();
        this.texture = GDReader.readEncString();
        if (this.version >= 5) {
            final int size = GDReader.readEncInt(true);
            this.lootFilters = new byte[size];
            for (int i = 0; i < this.lootFilters.length; ++i) {
                this.lootFilters[i] = GDReader.readEncByte();
            }
        }
        GDReader.readBlockEnd(block);
        this.changed = false;
    }

    public void write() throws IOException {
        final GDReader.Block block = new GDReader.Block();
        GDWriter.writeBlockStart(block, 1);
        GDWriter.writeInt(this.version);
        GDWriter.writeByte(this.isInMainQuest);
        GDWriter.writeByte(this.hasBeenInGame);
        GDWriter.writeByte(this.difficulty);
        GDWriter.writeByte(this.greatestCampaignDifficulty);
        GDWriter.writeInt(this.money);
        if (this.version >= 4) {
            GDWriter.writeByte(this.greatestCrucibleDifficulty);
            GDWriter.writeInt(this.tributes);
        }
        GDWriter.writeByte(this.compassState);
        if (this.version >= 2 && this.version <= 4) {
            GDWriter.writeInt(this.lootMode);
        }
        GDWriter.writeByte(this.skillWindowHelp);
        GDWriter.writeByte(this.alternateConfig);
        GDWriter.writeByte(this.alternateConfigEnabled);
        GDWriter.writeString(this.texture);
        if (this.version >= 5) {
            GDWriter.writeInt(this.lootFilters.length);
            for (int i = 0; i < this.lootFilters.length; ++i) {
                GDWriter.writeByte(this.lootFilters[i]);
            }
        }
        GDWriter.writeBlockEnd(block);
        this.changed = false;
    }

    public int getByteSize() {
        int size = 0;
        size += 4;
        size += 4;
        size += 4;
        ++size;
        ++size;
        ++size;
        ++size;
        size += 4;
        if (this.version >= 4) {
            ++size;
            size += 4;
        }
        ++size;
        if (this.version >= 2 && this.version <= 4) {
            size += 4;
        }
        ++size;
        ++size;
        ++size;
        size += 4;
        if (this.texture != null) {
            size += this.texture.length();
        }
        if (this.version >= 5) {
            size += 4;
            size += this.lootFilters.length;
        }
        size += 4;
        return size;
    }
}
